package com.member.api.SMUtils;


import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

import org.apache.commons.codec.binary.Base64;

@SuppressWarnings({ "restriction" })
public class ThreeDES {
    private static final String IV = "union968";
    ///public static final String KEY = "unionpay9683092019061114";
    private static String PARAM_AND_CHAR = "&";
	private static String PARAM_ASSIGN_CHAR = "=";
    /**
     * DESCBC加密
     * @param src数据源
     * @param key密钥，长度必须是8的倍数
     * @return 返回加密后的数据
     * @throws Exception
     */
    public String encryptDESCBC(final String src, final String key) throws Exception {
        // --生成key,同时制定是des还是DESede,两者的key长度要求不同
        final DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8"));
        final SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        final SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
        // --加密向量
        final IvParameterSpec iv = new IvParameterSpec(IV.getBytes("UTF-8"));
        // --通过Chipher执行加密得到的是一个byte的数组,Cipher.getInstance("DES")就是采用ECB模式,cipher.init(Cipher.ENCRYPT_MODE,
        // secretKey)就可以了.
        final Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
        final byte[] b = cipher.doFinal(src.getBytes("UTF-8"));

        // --通过base64,将加密数组转换成字符串
        final BASE64Encoder encoder = new BASE64Encoder();
        return encoder.encode(b);
    }

    /**
     * 3DES解密
     * @param src数据源
     * @param key密钥，长度必须是8的倍数
     * @return 返回解密后的原始数据
     * @throws Exception
     */
    public String decryptDESCBC(final String src, final String key) throws Exception {
        // --通过base64,将字符串转成byte数组
        final BASE64Decoder decoder = new BASE64Decoder();
        final byte[] bytesrc = decoder.decodeBuffer(src);

        // --解密的key
        final DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8"));
        final SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        final SecretKey secretKey = keyFactory.generateSecret(desKeySpec);

        // --向量
        final IvParameterSpec iv = new IvParameterSpec(IV.getBytes("UTF-8"));

        // --Chipher对象解密Cipher.getInstance("DES")就是采用ECB模式,cipher.init(Cipher.DECRYPT_MODE,
        // secretKey)就可以了.
        final Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);
        final byte[] retByte = cipher.doFinal(bytesrc);

        return new String(retByte);

    }

    // 3DESECB加密,key必须是长度大于等于 3*8 = 24 位
    public String encryptThreeDESECB(final String src, final String key) throws Exception {
        final DESedeKeySpec dks = new DESedeKeySpec(key.getBytes("UTF-8"));
        final SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
        final SecretKey securekey = keyFactory.generateSecret(dks);

        final Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, securekey);
        final byte[] b = cipher.doFinal(src.getBytes());

        final BASE64Encoder encoder = new BASE64Encoder();
        return encoder.encode(b).replaceAll("\r", "").replaceAll("\n", "");

    }

    // 3DESECB解密,key必须是长度大于等于 3*8 = 24 位哈
    public String decryptThreeDESECB(final String src, final String key) throws Exception {
        // --通过base64,将字符串转成byte数组
        final BASE64Decoder decoder = new BASE64Decoder();
        final byte[] bytesrc = decoder.decodeBuffer(src);
        // --解密的key
        final DESedeKeySpec dks = new DESedeKeySpec(key.getBytes("UTF-8"));
        final SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
        final SecretKey securekey = keyFactory.generateSecret(dks);

        // --Chipher对象解密
        final Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, securekey);
        final byte[] retByte = cipher.doFinal(bytesrc);

        return new String(retByte);
    }
    /**
	 * 生成验签内容
	 * @return
	 */
	public static String generateSignature(String json, String authorizationKey) {
		String sign = null;
		try {
			sign = encode(JSONObject.parseObject(json), authorizationKey);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return sign;
	}

	public static String encode(Map<String, Object> requestData, String authorizationKey) throws NoSuchAlgorithmException {
		String sortRespJson = buildSortJson(requestData) + authorizationKey;
		return md5(sortRespJson);
	}
	
	private static String buildSortJson(Map<String, Object> requestData) {
		StringBuffer sortSb = new StringBuffer();
		List<String> jsonKeys = new ArrayList<>();
		for (String key : requestData.keySet()) {
			jsonKeys.add(key);
		}
		Collections.sort(jsonKeys);
		for (String jsonKey : jsonKeys) {
			if (requestData.get(jsonKey) != null) {
				if (sortSb.length() > 0) {
					sortSb.append(PARAM_AND_CHAR);
				}
				sortSb.append(jsonKey).append(PARAM_ASSIGN_CHAR).append(requestData.get(jsonKey));
			}
		}
		return sortSb.toString();
	}
	
	/** 获得MD5加密算法 **/
	private static String md5(String inStr){
		String result = "";
		MessageDigest md5 = null;
		try {
			md5 = MessageDigest.getInstance("MD5");
			// 这句是关键
			md5.update(inStr.getBytes("UTF-8"));
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		byte b[] = md5.digest();
		int i;
		StringBuffer buf = new StringBuffer("");
		for (int offset = 0; offset < b.length; offset++) {
			i = b[offset];
			if (i < 0) {
				i += 256;
			}
			if (i < 16) {
				buf.append("0");
			}
			buf.append(Integer.toHexString(i));
		}
		result = buf.toString();

		return result;
	}

    public static void main(String[] args) throws Exception {
		JSONObject json2 = new JSONObject();
		json2.put("accSplitType", "2");
		json2.put("accSplitRuleId", "111");
		String binaryData= JSON.toJSONString(json2);
		Base64 s =new Base64();
		String accSplitData = new String(s.encode(binaryData.getBytes()));

		System.out.println("accSplitData:" + accSplitData);

        final String key = "97df19598e254be39c43ecf3c46685ed";//"fbd0ca39632544819c081722adc7ac30";
        ThreeDES threeDES = new ThreeDES();

        JSONObject json = new JSONObject();
		json.put("channelId", "ZJHEALTHCARDZLB");
		json.put("userName", "gNCp5e15FkMCvnsKF1/Kzg==");
		json.put("cardID", "ETHsPvmXnIk+2pbE7W8H0sb0qQlgkiHU");
		json.put("mobile", "7Jy3wZ2PQfflHHI3PNIVrw==");
		json.put("timestamp", "20200615135152");
        String sign = threeDES.generateSignature(JSON.toJSONString(json),key);

        System.out.println("sign:" + sign);

       String encrptyStr =  threeDES.encryptDESCBC("38d4d86f94c74e5e8820751de7806c04","8982be8bc2f04afd85a146a255a5c62b");

       System.out.println("encrptyStr:" + encrptyStr);
        // 解密流程
        //String id_decrypt = threeDES.decryptDESCBC(id_encrypt, key);
        String id_decrypt = threeDES.decryptDESCBC("vkpKuqLfN1ZZwX8zPL5fjg==","8a14bd5648e248cea37cd85459e99832");
        // bankCardType=&c2b=&cardID=hMjuJrtSLrzVag3dxpKRMgeMHKdUde0X&channelId=YHFCHL34000002&msg=成功&orderId=1000002500000000001&reserved=&status=OK&termId=&timestamp=20201202125210&tradeNo=&userName=ozNKlX8SC3EFX6xcssc+ZBd2EnKsmjiwbiRwCnL5igM=
        System.out.println("decryptStr:" + URLDecoder.decode(id_decrypt, "UTF-8"));
        
      /*  JSONObject json = new JSONObject();
		json.put("channelId", "ZJHEALTHCARDZLB");
		json.put("userName", "gNCp5e15FkMCvnsKF1/Kzg==");
		json.put("cardID", "ETHsPvmXnIk+2pbE7W8H0sb0qQlgkiHU");
		json.put("mobile", "7Jy3wZ2PQfflHHI3PNIVrw==");
		json.put("timestamp", "20200610135701");
        
        String authorization = generateSignature(JSON.toJSONString(json),"97df19598e254be39c43ecf3c46685ed");
        
        System.out.println("authorization:" + authorization);*/

//		String ss = "aHR0cHM6Ly90c3AuOTU1MTYuY29tL3RzcG1nbWh0dHBzOi8vdHNwLjk1NTE2LmNvbS90c3BtZ20vcmVzL3B1c2hJbnNJbmYvMTUwMDE4MTcwMC9hcHBsb2dvXzE1MDAxODE3MDAucG5n";
//
//		System.out.println(new String(Base64.decodeBase64(ss)));

		String bypassPinMsgRequest ="eyJpc3N1ZXJpZCI6IjAzMTAwMDAwIiwibXNnVHlwZSI6ImJ5cGFzc1Bpbk1zZ1JlcXVlc3QiLCJyZXNwTXNnIjoi5YW25LuW6ZSZ6K%2BvIiwibXNnSUQiOiI2MjAwMDA4MDAyNzIwMjEwMTIyMTM1NDE0NjExOTQyIiwicmVzcENvZGUiOiI5OSJ9";
		String responseResult =new String(Base64.decodeBase64(URLDecoder.decode(bypassPinMsgRequest, "utf-8")));
		System.out.println(responseResult);
//
//		JSONObject json1 = JSON.parseObject(responseResult);
//		String respCode = json1.getString("respCode");
//		System.out.println(respCode);

    }

}
